package com.hmdp.config;

import org.babyfish.jimmer.sql.DraftInterceptor;
import org.babyfish.jimmer.sql.JSqlClient;
import org.babyfish.jimmer.sql.dialect.MySqlDialect;
import org.babyfish.jimmer.sql.filter.Filter;
import org.babyfish.jimmer.sql.runtime.ConnectionManager;
import org.babyfish.jimmer.sql.runtime.Executor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.util.List;
import java.util.function.Function;

@Configuration
public class SqlClientConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(SqlClientConfig.class);
    @Bean
    public JSqlClient sqlClient(
            DataSource dataSource,
            @Value("${spring.datasource.url}") String jdbcUrl,
            List<DraftInterceptor<?>> interceptors,
            List<Filter<?>> filters
    ) {
        return JSqlClient.newBuilder()
                .setConnectionManager(
                        /*
                         * It's very important to use
                         *      "org.springframework.jdbc.datasource.DataSourceUtils"!
                         * This is spring transaction aware ConnectionManager
                         */
                        new ConnectionManager() {
                            @Override
                            public <R> R execute(Function<Connection, R> block) {
                                Connection con = DataSourceUtils.getConnection(dataSource);
                                try {
                                    return block.apply(con);
                                } finally {
                                    DataSourceUtils.releaseConnection(con, dataSource);
                                }
                            }
                        }
                )
                .setDialect(new MySqlDialect())
                .setExecutor(Executor.log())
                .addDraftInterceptors(interceptors)
                .addFilters(filters)
                .build();
    }
}